package com.wswy.wzcx.ui.wzdb

import android.content.Context
import android.content.Intent
import android.os.Bundle
import android.support.annotation.Keep
import android.support.v4.content.ContextCompat
import android.support.v4.util.SparseArrayCompat
import android.text.SpannableString
import android.text.SpannableStringBuilder
import android.text.TextUtils
import android.text.style.ForegroundColorSpan
import android.util.Log
import android.view.Gravity
import android.view.View
import android.view.ViewGroup
import android.widget.LinearLayout
import android.widget.Space
import android.widget.TextView
import android.widget.Toast
import com.blankj.utilcode.util.SizeUtils
import com.che.libcommon.api.BaseResult
import com.che.libcommon.api.ProgressDialogObserver
import com.che.libcommon.utils.IntentUtils
import com.che.libcommon.utils.RxBus
import com.che.libcommon.utils.ToastUtils
import com.che.libcommon.utils.optional.Optional
import com.google.android.flexbox.FlexWrap
import com.google.android.flexbox.FlexboxLayout
import com.wswy.wzcx.R
import com.wswy.wzcx.api.Api
import com.wswy.wzcx.model.JZCFMode
import com.wswy.wzcx.model.core.EventNormal
import com.wswy.wzcx.model.core.postEvent
import com.wswy.wzcx.model.home.RPaths
import com.wswy.wzcx.model.home.RouterUtils
import com.wswy.wzcx.model.license.UserCarInfo
import com.wswy.wzcx.model.wzdb.AddUserCertEntry
import com.wswy.wzcx.model.wzdb.WzdbOrderInfo
import com.wswy.wzcx.model.wzdb.classify
import com.wswy.wzcx.module.GlobalConfigManager
import com.wswy.wzcx.module.InternalMsgCode
import com.wswy.wzcx.module.InternalMsgCodeKt
import com.wswy.wzcx.module.base.gone
import com.wswy.wzcx.ui.Constants
import com.wswy.wzcx.ui.activity.ModuleActivity
import com.wswy.wzcx.ui.activity.SampleBaseActivity
import com.wswy.wzcx.ui.data.Certs
import com.wswy.wzcx.ui.other.CloseDelegate
import com.wswy.wzcx.ui.pay.PayOrder
import com.wswy.wzcx.ui.pay.PayWzdbData
import com.wswy.wzcx.utils.FileUtils
import com.wswy.wzcx.utils.ImageUtils
import com.wswy.wzcx.utils.RxUtils
import com.wswy.wzcx.utils.getEColor
import com.wswy.wzcx.widget.EventMessage
import com.wswy.wzcx.widget.JzcfEventMessage
import com.wzcx.orclib.PhotoAgent
import io.reactivex.Single
import io.reactivex.schedulers.Schedulers
import kotlinx.android.synthetic.main.activity_wzdb_submit_cert.*
import org.greenrobot.eventbus.EventBus
import org.greenrobot.eventbus.Subscribe
import org.greenrobot.eventbus.ThreadMode
import timber.log.Timber
import java.io.File

/**
 * 违章代办->提交代办资料
 */
class WZDBSubmitCertActivity : SampleBaseActivity(), View.OnClickListener {

    companion object {
        private const val TAG = "WZDBSubmitCertActivity"
        private const val DIR = "wzdb/cert/"
        private const val ID_CARD_NAME = "${DIR}id_card_wzdb_%s.jpg"

        private const val REQ_PICK_GALLERY = 210

        private const val WZ_IDS = "extra.ids"
        private const val WZ_ORDER_NO = "extra.orderNo" //订单号

        private const val WZ_DATA_INFOS = "extra.data.infos"

        fun start(context: Context?, uniqueMd5Id: String, data: ArrayList<AddUserCertEntry>, userCarInfo: UserCarInfo) {
            context ?: return
            Intent(context, WZDBSubmitCertActivity::class.java).apply {
                putExtra(WZ_IDS, uniqueMd5Id)
                putParcelableArrayListExtra(WZ_DATA_INFOS, data)
                putExtra(Constants.EXTRA_DATA, userCarInfo)
            }.run {
                context.startActivity(this)
            }
        }

        /**
         * 补充资料
         */
        fun startUpload(context: Context?, orderNo: String, data: ArrayList<AddUserCertEntry>, userCarInfo: UserCarInfo) {
            context ?: return
            Intent(context, WZDBSubmitCertActivity::class.java).apply {
                putExtra(WZ_ORDER_NO, orderNo)
                putParcelableArrayListExtra(WZ_DATA_INFOS, data)
                putExtra(Constants.EXTRA_DATA, userCarInfo)
            }.run {
                context.startActivity(this)
            }
        }

    }

    private val deg = mutableMapOf<Int, Pair<CertCardSelectView, (Int, CertCardSelectView) -> Unit>>()

    private var currPath: String? = null
    private var currId: Int = 0
    private var delegate: CloseDelegate? = null
    private lateinit var userCarInfo: UserCarInfo
    private var orderNo: String? = null
    private lateinit var mInputAreaLayout: InputAreaLayout
    private lateinit var addUserCertEntry: AddUserCertEntry
    private var inputs = ArrayList<AddUserCertEntry>()
    private var lineH = SizeUtils.dp2px(48.toFloat())

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        EventBus.getDefault().register(this)
        setContentView(R.layout.activity_wzdb_submit_cert)
        setAppTitle("提交代办资料")
        val ids = intent?.getStringExtra(WZ_IDS)
        val userCar: UserCarInfo? = intent?.getParcelableExtra(Constants.EXTRA_DATA)

        delegate = CloseDelegate(this, InternalMsgCode.CODE_PAY_SUCCESS)

        orderNo = intent?.getStringExtra(WZ_ORDER_NO)

        GlobalConfigManager.getInstance().reloadConfig()

        if (userCar == null || (TextUtils.isEmpty(ids) && TextUtils.isEmpty(orderNo))) {
            ToastUtils.showText("未知id")
            finish()
            return
        }

        if (!orderNo.isNullOrEmpty()) {
            setAppTitle("补充资料")
            btn_submit.text = "确认提交"
        }
        userCarInfo = userCar
        val list = intent?.getParcelableArrayListExtra<AddUserCertEntry>(WZ_DATA_INFOS)
        File(filesDir, DIR).mkdirs()
        com.blankj.utilcode.util.FileUtils.deleteAllInDir(File(filesDir, DIR))

        val photos = ArrayList<AddUserCertEntry>()


        list?.forEach {
            if (it.isEditInput()) {
                inputs.add(it)
            } else {
                photos.add(it)
            }
        }

        if (inputs.isNullOrEmpty()) {
            //不用填车主信息
            ll_input_hint.gone()
            layout_container.gone()

        } else {
            tv_input_hint.text = SpannableStringBuilder().apply {
                append("请填写")
                append(SpannableString(userCarInfo.carNo).apply {
                    setSpan(ForegroundColorSpan(getEColor(R.color.accentColor3)), 0, length, SpannableString.SPAN_INCLUSIVE_EXCLUSIVE)
                })
                append("的车主信息、车辆信息")
            }

            var hasReq = false
            inputs.forEachIndexed { index, AddUserCertEntry ->
                addUserCertEntry = AddUserCertEntry
                val lp = LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, lineH)
                mInputAreaLayout = InputAreaLayout(this)
                mInputAreaLayout.bindEntry(index, AddUserCertEntry)
                if (!hasReq && AddUserCertEntry.defaultValue.isNullOrEmpty()) {
                    mInputAreaLayout.requestFocus()
                    hasReq = true
                }
                layout_container.addView(mInputAreaLayout, lp)
            }
        }

        //photos.clear()
//        photos.add(AddUserCertEntry("j1","行驶证正本正面","行驶证正本","file","",0,"VLOF"))
//        photos.add(AddUserCertEntry("j2","行驶证正本背面","行驶证正本","file","",0,"VLOB"))
//        photos.add(AddUserCertEntry("j3","行驶证副本正面","行驶证副本","file","",0,"VLCF"))
//        photos.add(AddUserCertEntry("j4","行驶证副本背面","行驶证副本","file","",0,"VLCB"))
//
//        photos.add(AddUserCertEntry("m1","驾驶证正本正面","驾驶证正本","file","",0,"DLOF"))
//        photos.add(AddUserCertEntry("m2","驾驶证正本背面","驾驶证正本","file","",0,"DLOB"))
//        photos.add(AddUserCertEntry("m3","驾驶证副本正面","驾驶证副本","file","",0,"DLCF"))
//        photos.add(AddUserCertEntry("m4","驾驶证副本背面","驾驶证副本","file","",0,"DLCB"))

//        photos.add(AddUserCertEntry("j2","行驶证正本背面","行驶证正本","file","",0,"VLOB"))
//        photos.add(AddUserCertEntry("m3","驾驶证副本正面","驾驶证副本","file","",0,"DLCF"))
//        photos.add(AddUserCertEntry("m4","驾驶证副本背面","驾驶证副本","file","",0,"DLCB"))
//        photos.add(AddUserCertEntry("m1","驾驶证正本正面","驾驶证正本","file","",0,"DLOF"))
//        photos.add(AddUserCertEntry("j1","行驶证正本正面","行驶证正本","file","",0,"VLOF"))
//        photos.add(AddUserCertEntry("j3","行驶证副本正面","行驶证副本","file","",0,"VLCF"))
//        photos.add(AddUserCertEntry("j4","行驶证副本背面","行驶证副本","file","",0,"VLCB"))
//
//
//        photos.add(AddUserCertEntry("p4","行驶证副本背面","行驶证副本","file","",0,"sdf"))
//
        //photos.add(AddUserCertEntry("m2","车主上半身自拍照","车主上半身自拍照","file","",0,"OUP"))


        //分类
        if (photos.isNullOrEmpty()) {
            layout_certs.gone()

        } else {
            //布局图片
            val layout = layout_certs
            val topM = SizeUtils.dp2px(15.toFloat())
            val rowHeight = SizeUtils.dp2px(146f)
            var idN = 15200
            val titleLayout = LinearLayout(this).apply {
                orientation = LinearLayout.HORIZONTAL
                gravity = Gravity.CENTER_VERTICAL
            }
            val tvTitle = TextView(this).apply {
                text = " *需车主本人驾照，非本人本证无法网上办理 "
                textSize = 13f
                setTextColor(ContextCompat.getColor(applicationContext, R.color.accentColor3))
                setPadding(SizeUtils.dp2px(5f), SizeUtils.dp2px(10f), SizeUtils.dp2px(5f), SizeUtils.dp2px(10f))
            }
            tvTitle.setBackgroundResource(R.color.red_bg_color)
            titleLayout.addView(tvTitle, ViewGroup.MarginLayoutParams(ViewGroup.MarginLayoutParams.WRAP_CONTENT, ViewGroup.MarginLayoutParams.WRAP_CONTENT).apply {
                topMargin = SizeUtils.dp2px(10f)
            })
            layout.addView(titleLayout, ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT))

            classify(photos).forEach {
                val titleLayout = LinearLayout(this).apply {
                    orientation = LinearLayout.HORIZONTAL
                    gravity = Gravity.CENTER_VERTICAL
                }

                val title = it.getTitle()
                val titleHint = when (it.type) {
                    CertDataEntry.TYPE_VL -> SpannableStringBuilder().apply {
                        append("请填写")
                        append(SpannableString(userCarInfo.carNo).apply {
                            setSpan(ForegroundColorSpan(getEColor(R.color.accentColor3)), 0, length, SpannableString.SPAN_INCLUSIVE_EXCLUSIVE)
                        })
                        append("的行驶证")
                    }
                    CertDataEntry.TYPE_USER_FACE -> "请上传车主本人自拍照，背景为纯色背景"
                    else -> "请确保照片清晰"
                }

                val tvTitle = TextView(this).apply {
                    text = title
                    textSize = 16f
                    setTextColor(ContextCompat.getColor(applicationContext, R.color.textColorPrimary))
                }
                val tvTitleHint = TextView(this).apply {
                    text = titleHint
                    textSize = 12f
                    setTextColor(ContextCompat.getColor(applicationContext, R.color.textColorPrimary_40))
                }

                //标题
                titleLayout.addView(tvTitle)
                titleLayout.addView(tvTitleHint, ViewGroup.MarginLayoutParams(ViewGroup.MarginLayoutParams.WRAP_CONTENT, ViewGroup.MarginLayoutParams.WRAP_CONTENT).apply {
                    leftMargin = SizeUtils.dp2px(4f)
                })

                layout.addView(titleLayout, ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, SizeUtils.dp2px(54f)))

                val imgContainer = FlexboxLayout(this).apply {
                    flexWrap = FlexWrap.WRAP
                }

                layout.addView(imgContainer, ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT))

                it.list.forEachIndexed { index, addUserCertEntry ->
                    val view = CertCardSelectView(this)
                    view.id = ++idN
                    view.bindEntry(index, addUserCertEntry)
                    view.setOnClickListener(this)
                    deg[view.id] = Pair(view, handlePhoto)

                    val lp = FlexboxLayout.LayoutParams(0, rowHeight).apply {
                        flexGrow = 1f
                    }

                    if (index % 2 == 0) {
                        lp.isWrapBefore = true
                        lp.rightMargin = SizeUtils.dp2px(8f)
                    } else {
                        lp.leftMargin = SizeUtils.dp2px(8f)
                    }

//                    if (index/2 > 0 ){
//                        lp.topMargin = topM
//                    }
                    imgContainer.addView(view, lp)
                }

                //填充空白
                if (it.list.size % 2 > 0) {
                    val lp = FlexboxLayout.LayoutParams(0, rowHeight).apply {
                        leftMargin = SizeUtils.dp2px(8f)
                    }
                    lp.flexGrow = 1f
                    imgContainer.addView(Space(this), lp)
                }

            }

        }

    }


    private val handlePhoto = fun(id: Int, view: CertCardSelectView) {

        var saveFile = if (TextUtils.isEmpty(currPath)) null else File(currPath)

        if (saveFile == null || !saveFile.exists()) {
            saveFile = FileUtils.getSaveFile(this, currPath)
        }


        saveFile?.let {

            if (it.exists()) {
                view.imgPath = it.absolutePath
            }

        }

    }

    override fun onClick(v: View?) {

        currPath = null
        v?.let { view ->

            val pos = view.id

            val alias = deg[pos]?.first?.certEntry?.alias

            if (alias == "OUP") {
                currPath = ID_CARD_NAME.format(System.currentTimeMillis())
                val path = FileUtils.getSaveFile(applicationContext, currPath)?.absolutePath
                ModuleActivity.getTargetIntent(this, UserFaceFragment.TAG, Bundle().apply {
                    putString(Constants.EXTRA_DATA, path)
                }).let {
                    startActivityForResult(it, pos)
                }

            } else {
                val dialog = ChooseCertDialog(this, deg[pos]?.first?.certEntry?.alias)
                dialog.onChooseListener = object : ChooseCertDialog.OnChooseListener {
                    override fun onStartCamera() {
                        currPath = ID_CARD_NAME.format(System.currentTimeMillis())
                        FileUtils.getSaveFile(applicationContext, currPath)?.let {
                            startPhoto(pos, it.absolutePath, dialog.key)
                        }

                    }

                    override fun onStartGallery() {
                        currId = view.id
                        //startGallery(view.id)
                        val pos = view.id
                        currPath = ID_CARD_NAME.format(System.currentTimeMillis())
                        FileUtils.getSaveFile(applicationContext, currPath)?.let {
                            startGallery(pos, it.absolutePath, dialog.key)
                        }

                    }

                }

                dialog.show()
            }

        }


    }


    fun clickSubmit(view: View) {
        extraInput()?.let { data ->
            Single.just(data).observeOn(Schedulers.io()).map {
                val ret = mutableMapOf<String, Any>()
                data.forEach { (t, u) ->
                    if (u is File) {
                        try {
                            ret[t] = ImageUtils.compress(u.absolutePath).absoluteFile
                        } catch (e: Throwable) {
                            e.printStackTrace()
                            ret[t] = u
                        }

                    } else {
                        ret[t] = u
                    }
                }

                ret
            }.flatMap { datas ->

                Single.fromCallable {

                    try {
                        val files = datas.filterValues { it is File }.mapValues { it.value as File }
                        Timber.e("files --> $files")

                        Api.get().uploadFiles("wzdb", files).compose(RxUtils.switch2io()).blockingGet()?.forEach { (t, u)
                            ->
                            u?.objectKey?.let {
                                datas[t] = it
                            }
                        }
                    } catch (e: Throwable) {
                        e.printStackTrace()
                    }

                    datas
                }

            }.flatMap { submitData(it) }
                    .subscribe(object : ProgressDialogObserver<WzdbOrderInfo>(this, "提示", "代办资料提交中，请稍后") {

                        override fun onApiResult(t: WzdbOrderInfo?) {

                            if (!orderNo.isNullOrEmpty()) {
                                //提交补充资料
                                postEvent(EventNormal(InternalMsgCodeKt.ORDER_STATUS_CHANGED, null))
                                ToastUtils.showText("上传成功")
                                RxBus.getDefault().postWithCode(InternalMsgCodeKt.UPLOAD_COMPLETE_WDZD, "")
                                RxBus.getDefault().postWithCode(InternalMsgCodeKt.ORDER_STATUS_CHANGED, "")

                                ImageUtils.clearCache()
                                finish()

                                return
                            }

                            if (t != null) {
                                //支付

                                if (orderNo.isNullOrEmpty()) {
                                    RouterUtils.startPage(this@WZDBSubmitCertActivity, RPaths.PAY_ORDER, Bundle().apply {
                                        putParcelable(Constants.EXTRA_DATA, PayOrder(PayOrder.TYPE_WZDB, PayWzdbData(t, userCarInfo)))
                                    })
                                }
                                //上传成功
                                ImageUtils.clearCache()
                            } else {
                                ToastUtils.showText("上传失败，请重试!")
                            }

                        }

                        override fun onApiError(result: BaseResult<*>?) {
                            toastErrorMsg(result)
                        }

                    })


        }

    }


    private fun submitData(data: Map<String, Any>): Single<Optional<WzdbOrderInfo?>> {
        if (orderNo?.isNotEmpty() == true) {
            return Api.get().submitNeedParams(orderNo, data)
        }
        return Api.get().addWZDBCertInfo(intent?.getStringExtra(WZ_IDS), data)
    }

    private fun extraInput(): Map<String, Any>? {
        val datas = mutableMapOf<String, Any>()
        val views = arrayOf(layout_container, layout_certs)
        views.forEach {
            if (it.isShown && !getValues(it, datas)) {
                return null
            }
        }
        return datas
    }


    @Keep
    @Subscribe(threadMode = ThreadMode.MAIN, sticky = true)
    fun onMessages(message: JzcfEventMessage) {
        EventBus.getDefault().removeStickyEvent(message)
        if (message != null) {
            layout_container.removeAllViews()
            inputs.forEachIndexed { index, AddUserCertEntry ->
                if (AddUserCertEntry.alias == "DLU" || AddUserCertEntry.alias == "DLN") {
                    AddUserCertEntry.defaultValue = message.message.number.toString()
                }
                if (AddUserCertEntry.alias == "DLFN") {
                    AddUserCertEntry.defaultValue = message.message.fileNumber.toString()
                }
                val lp = LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, lineH)
                mInputAreaLayout = InputAreaLayout(this)
                mInputAreaLayout.bindEntry(index, AddUserCertEntry)
                layout_container.addView(mInputAreaLayout, lp)
            }
        }
    }

    private fun getValues(layout: ViewGroup, datas: MutableMap<String, Any>): Boolean {
        // 提取信息
        for (i in 0 until layout.childCount) {
            val childAt = layout.getChildAt(i)
            when (childAt) {
                is IInputView -> {
                    if (childAt.value == null || TextUtils.isEmpty(childAt.value?.toString())) {
                        ToastUtils.showText("请输入${childAt.info?.label}")
                        return false
                    }
                    childAt.info?.key?.let {
                        datas[it] = childAt.value
                    }
                }
                is FlexboxLayout -> {

                    for (j in 0 until childAt.childCount) {
                        val childAtPhoto = childAt.getChildAt(j)

                        if (childAtPhoto is IInputView) {

                            if (childAtPhoto.value == null || (childAtPhoto.value is File && !(childAtPhoto.value as File).exists())) {
                                ToastUtils.showText("请输入${childAtPhoto.info?.label}")
                                return false
                            }
                            childAtPhoto.info?.key?.let {
                                datas[it] = childAtPhoto.value
                            }
                        }
                    }
                }
            }

        }
        return true
    }

    override fun onDestroy() {
        super.onDestroy()
        if (EventBus.getDefault().isRegistered(this)) {
            EventBus.getDefault().unregister(this)
        }
        delegate?.onDestroy()
    }

    private fun startPhoto(id: Int, path: String, key: String?) {
        val intent = PhotoAgent.getPhotoIntent(this, path, Certs.photoHints[key])
        startActivityForResult(intent, id)
    }

    private fun startGallery(id: Int, path: String, key: String?) {
        val intent = PhotoAgent.getPhotoIntent(this, path, Certs.photoHints[key], true)
        startActivityForResult(intent, id)
    }


    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)
        if (resultCode == RESULT_OK) {
            if (requestCode == REQ_PICK_GALLERY) {
                currPath = File(IntentUtils.extraImageFromGallery(applicationContext, data)).absolutePath
                deg[currId]?.let {
                    it.second.invoke(requestCode, it.first)
                }
            } else {
                deg[requestCode]?.let {
                    Log.e(UserFaceFragment.TAG, "拍照返回----------->>>>$it$requestCode")
                    it.second.invoke(requestCode, it.first)
                }
            }
        }


    }

}